/**
 *	@file	np_time.c
 *	@brief	木の実プランター成長ルーチン制御
 *	@author	Miyuki Iwasawa
 *	@date	08.08.19
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "gflib/touchpanel.h"
#include "itemtool/item.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_n_planter.h"

#include "savedata/config.h"
#include "application/nut_planter.h"
#include "np_sys.h"
#include "np_tool.h"
#include "np_app.h"
#include "np_sub.h"
#include "np_time.h"
#include "np_snd_def.h"
#include "nuts.h"

//状態遷移エフェクトタスク構造体
typedef struct _VIEW_UPDATE_EFF{
	NP_APPWORK* app_wk;
	u8			id;
	u8			ct;
	u8			seq;
}VIEW_UPDATE_EFF;

static void NPTime_SeedViewUpdate(NP_APPWORK* wk);
static void tcb_SeedViewUpdate( TCB_PTR tcb, void* p_work );

#ifdef PM_DEBUG
static void deb_TimePrint(NP_APPWORK* wk,
	RTCDate ndate,RTCTime ntime,RTCDate sdate,RTCTime stime,s32 diff);
#endif	//PM_DEBUG

/**
 *	@brief	時間取得&更新
 */
void NPTime_Update(NP_APPWORK* wk,BOOL view_f)
{
	s64 now, sv;
	s32 diff_minute;
	RTCDate ndate,sdate;
	RTCTime	ntime,stime;

	//現在のRTC時刻を取得
	GF_RTC_GetDateTime(&ndate, &ntime);
	now = RTC_ConvertDateTimeToSecond(&ndate, &ntime);

	//セーブデータの時刻を取得
	SEEDTIME_Get(wk->seed_time,&sdate,&stime);
	sv = RTC_ConvertDateTimeToSecond(&sdate, &stime);

	if (now < sv) {
		//現在　＜　過去　…ありえないはず
		//現在時間をセットするだけで戻る
		SEEDTIME_Update(wk->seed_time,ndate,ntime);
		return;
	}

#ifdef PM_DEBUG
	//タイムレート変更
	if(sys.trg & PAD_BUTTON_START){
		wk->deb_time_rate = (wk->deb_time_rate+1)%3;
		switch(wk->deb_time_rate){
		case 1:
			DEBUG_StartFakeTime(60);
			break;
		case 2:
			DEBUG_StartFakeTime(600);
			break;
		default:
			DEBUG_StopFakeTime();
		}
	}
	if(sys.trg & PAD_BUTTON_SELECT){
		if(wk->deb_print){
			GF_BGL_ScrClearCodeVReq( wk->bgl, UFRM_MSG, 0);
		}
		wk->deb_print ^= 1;
		wk->deb_ct = 0;
		Deb_SeedPrint(wk);
	}

	if(wk->deb_print && wk->deb_ct++ == 0){
		deb_TimePrint(wk,ndate,ntime,sdate,stime,now-sv);
		wk->deb_ct = 0;
	}
#endif

	//分
	diff_minute = (now-sv) / 60;
	if (diff_minute == 0) {
		return;
	}
	//きのみ成長処理を呼ぶ
	SEEDBED_Growth(wk->seed_bed, wk->seed_prm, diff_minute);
	NPTime_SeedStateUpdate( wk );

	//現在時間更新
	SEEDTIME_Update(wk->seed_time,ndate,ntime);

	//画面描画更新
	if(view_f){
		NPTime_SeedViewUpdate( wk );
	}

#ifdef PM_DEBUG
	if(!wk->deb_print){
		return;
	}
	if(!wk->deb_ct){
		deb_TimePrint(wk,ndate,ntime,sdate,stime,now-sv);
	}
	Deb_SeedPrint(wk);
	wk->deb_ct = 0;
#endif

}

/**
 *	@brief	現在の木の実の状態を取得
 */
void NPTime_SeedStateUpdate(NP_APPWORK* wk)
{
	int i;

	for(i = 0;i < SEEDBED_MAX;i++){
		//今の状態を保存
		wk->seed[i].o_type = wk->seed[i].type;
		wk->seed[i].o_stat = wk->seed[i].stat;
		wk->seed[i].o_ground_st = wk->seed[i].ground_st;

		//状態更新
		wk->seed[i].type = SEEDBED_GetSeedType(wk->seed_bed,i);
		wk->seed[i].stat = SEEDBED_GetSeedStatus(wk->seed_bed,i);
		wk->seed[i].seed_hp = SEEDBED_GetSeedHP(wk->seed_bed,i);
		wk->seed[i].ground_hp = SEEDBED_GetGroundStatusNum(wk->seed_bed,i);
		wk->seed[i].compost = SEEDBED_GetCompost(wk->seed_bed,i);

		wk->seed[i].nuts_ct = SEEDBED_GetSeedCount(wk->seed_bed, i);
		wk->seed[i].grow_tm = SEEDBED_GetGrowTime(wk->seed_bed, i);
		wk->seed[i].dry_tm = SEEDBED_GetDryTime(wk->seed_bed, i);

		wk->seed[i].ground_st = SEEDBED_GetGroundStatus(wk->seed_bed, i);
	}
}

/**
 *	@brief	木の実状態遷移
 */
static void NPTime_SeedViewUpdate(NP_APPWORK* wk)
{
	int i;
	SEED_STATE* st;
	VIEW_UPDATE_EFF* ep;

	for(i = 0;i < SEEDBED_MAX;i++){
		st = &wk->seed[i];

		//地面の状態遷移
		if(st->ground_st != st->o_ground_st){
			CLACT_AnmFrameSet( wk->pAct[ACT_SOIL01+i] ,st->ground_st);

			if(st->stat == SEEDSTAT_UNDERGROUND){
				CLACT_AnmFrameSet( st->act , st->ground_st);
			}
		}
		//木の実の状態遷移
		if(st->stat == st->o_stat){
			continue;
		}

		//状態遷移エフェクトタスクを追加
		ep = sys_AllocMemory(wk->heapID,sizeof(VIEW_UPDATE_EFF));
		MI_CpuClear8(ep,sizeof(VIEW_UPDATE_EFF));
		ep->app_wk = wk;
		ep->id = i;
		TCB_Add( tcb_SeedViewUpdate, ep, 0);
		++wk->eff_tcb_ct;
	}
}

/**
 *	@brief	木の実状態更新エフェクト
 */
static void tcb_SeedViewUpdate( TCB_PTR tcb, void* p_work )
{
	VIEW_UPDATE_EFF* ep = (VIEW_UPDATE_EFF*)p_work;
	NP_APPWORK* wk = ep->app_wk;

	switch(ep->seq){
	case 0:
		//キラキラ表示開始
		CLACT_SetDrawFlag(wk->pAct[ACT_KIRA01 + ep->id], TRUE );
		Snd_SePlay( SND_NP_EFFECT );
		ep->seq++;
		break;
	case 1:
		if(ep->ct++ == 15){
			//描画更新
			NPSub_SeedActorSet( wk , ep->id );
			if(wk->c_pos == ep->id){	//カーソルの状態更新
				NPSub_CursorPosSet(wk);
			}
		}
		if(ep->ct < 30){
			return;
		}
		CLACT_SetDrawFlag(wk->pAct[ACT_KIRA01 + ep->id], FALSE );
		--wk->eff_tcb_ct;

		// メモリ解放
		sys_FreeMemoryEz(p_work);
		TCB_Delete( tcb );
	}
}

/********************************************************************************/
//////////////////////////////////////////////////////////////////////////////////
//デバッグ用
//////////////////////////////////////////////////////////////////////////////////
/********************************************************************************/
#ifdef PM_DEBUG

#define DEB_PRINT_COL	(GF_PRINTCOLOR_MAKE(3,2,0))

static void deb_TimePrint(NP_APPWORK* wk,
	RTCDate ndate,RTCTime ntime,RTCDate sdate,RTCTime stime,s32 diff)
{
	static const u16 time_rate[] = {1,60,600};

	GF_BGL_BmpWinDataFill(&wk->deb_win[DEB_WIN_TIME],0);

	WORDSET_RegisterNumber( wk->msg.wset, 0,
		ndate.year , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 1,
		ndate.month , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 2,
		ndate.day , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );

	WORDSET_RegisterNumber( wk->msg.wset, 3,
		ntime.hour , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 4,
		ntime.minute , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 5,
		ntime.second , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );

	WORDSET_RegisterNumber( wk->msg.wset, 6,
		sdate.year , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 7,
		sdate.month , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 8,
		sdate.day , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );

	WORDSET_RegisterNumber( wk->msg.wset, 9,
		stime.hour , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 10,
		stime.minute , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 11,
		stime.second , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );

	WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.deb[DMIDX_TIME01]);

	GF_STR_PrintColor( &wk->deb_win[DEB_WIN_TIME], FONT_SYSTEM, wk->msg.tmp,
		0,0, MSG_NO_PUT, DEB_PRINT_COL, NULL );

	//差分
	WORDSET_RegisterNumber( wk->msg.wset, 0,
		(diff/60/60) , 6, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 1,
		(diff/60) , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 2,
		(diff%60) , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );

	//タイムレート
	WORDSET_RegisterNumber( wk->msg.wset, 3,
		 time_rate[wk->deb_time_rate], 3, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );

	WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.deb[DMIDX_TIME02]);

	GF_STR_PrintColor( &wk->deb_win[DEB_WIN_TIME], FONT_SYSTEM, wk->msg.tmp,
		0,16, MSG_NO_PUT, DEB_PRINT_COL, NULL );

	GF_BGL_BmpWinOnVReq(&wk->deb_win[DEB_WIN_TIME]);
}

void Deb_SeedPrint(NP_APPWORK* wk)
{
	int i;
	SEED_STATE* st;

	if(!wk->deb_print){
		return;
	}
	for(i = 0;i < SEEDBED_MAX;i++){
		st = &wk->seed[i];

		GF_BGL_BmpWinDataFill(&wk->deb_win[DEB_WIN_SEED01+i],0);

		if(st->compost == 0){
			WORDSET_RegisterWord( wk->msg.wset, 1, wk->msg.deb[DMIDX_NOTHING],
				PM_NEUTRAL, FALSE, PM_LANG );
		}else{
			WORDSET_RegisterItemName( wk->msg.wset, 0, SeedSys_Compost2Item(st->compost) );
		}
		if(st->stat == SEEDSTAT_NOTHING){
			WORDSET_RegisterWord( wk->msg.wset, 0, wk->msg.deb[DMIDX_NOTHING],
				PM_NEUTRAL, FALSE, PM_LANG );
			WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.deb[DMIDX_SEED01]);
		}else{
			WORDSET_RegisterItemName( wk->msg.wset, 0, SeedSys_Nuts2Item(st->type) );

			//状態
			if(st->stat == 0xFF){
				WORDSET_RegisterNumber( wk->msg.wset, 2,
					9 , 1, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
			}else{
				WORDSET_RegisterNumber( wk->msg.wset, 2,
					st->stat , 1, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
			}
			WORDSET_RegisterNumber( wk->msg.wset, 3,
				st->nuts_ct , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );

			WORDSET_RegisterNumber( wk->msg.wset, 4,
				st->grow_tm , 4, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
			WORDSET_RegisterNumber( wk->msg.wset, 5,
				st->dry_tm , 3, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
			WORDSET_RegisterNumber( wk->msg.wset, 6,
				st->seed_hp , 2, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );
			WORDSET_RegisterNumber( wk->msg.wset, 7,
				st->ground_hp , 3, NUMBER_DISPTYPE_ZERO, NUMBER_CODETYPE_HANKAKU );

			WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.deb[DMIDX_SEED02]);
		}
		GF_STR_PrintColor( &wk->deb_win[DEB_WIN_SEED01+i], FONT_SYSTEM, wk->msg.tmp,
			0,0, MSG_NO_PUT, DEB_PRINT_COL, NULL );

		GF_BGL_BmpWinOnVReq(&wk->deb_win[DEB_WIN_SEED01+i]);
	}
}

#endif	//PM_DEBUG
